﻿using System.Net;
using System.Printing.IndexedProperties;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1;

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    Button button = new Button { Content = "Go" };
    TextBlock _results = new TextBlock();
    static Dictionary<string, string> _catch = new Dictionary<string, string>();
    static Dictionary<string, Task<string>> taskCatch = new Dictionary<string, Task<string>>();
    public MainWindow()
    {
        InitializeComponent();

        var panel = new StackPanel();
        panel.Children.Add(button);
        panel.Children.Add(_results);
        Content = panel;
        button.Click += async (sender, args) => await Go();
        //button.Click += (sender, args) =>
        //{
        //    button.IsEnabled = false;
        //    Task.Run(async () => await Go());
        //};
    }

    /* private async Task Go()
     {
         button.IsEnabled = false;

         string[] urls = "www.albahari.com www.oreilly.com www.liqpad.net".Split();
         int totalLength = 0;
         try
         {
             foreach (string url in urls)
             {
                 var uri = new Uri("http://" + url);
                 byte[] data = await new WebClient().DownloadDataTaskAsync(uri);
                 _results.Text += "Length of " + url + " is " + data.Length + Environment.NewLine;
                 totalLength += data.Length;
             }
             _results.Text += "Total length: " + totalLength;
         }
         catch (WebException ex)
         {
             _results.Text += "Error: " + ex.Message;

         }
         finally
         {
             button.IsEnabled = true;
         }

         //for (int i = 1; i < 5; i++)
         //{
         //    _results.Text += await GetPrimesCountAsync(i * 1000000, 1000000) + " primes between " + (i * 1000000) + " and " + ((i + 1) * 1000000 - 1) + Environment.NewLine;
         //    button.IsEnabled = true;
         //}
     }

     void Go2()
     {
         for (int i = 1; i < 5; i++)
         {
             int result = GetPrimesCount(i * 1000000, 1000000);
             Dispatcher.BeginInvoke(new Action(() => _results.Text += result + " primes between " + (i * 1000000) + " and " + ((i + 1) * 1000000 - 1) + Environment.NewLine));
         }
         Dispatcher.BeginInvoke(new Action(() => button.IsEnabled = true));
     }*/

    /* async Task Go3()
    {
        await PrintAnswerToLife();
        Console.WriteLine("Done");
    }
     
      async Task PrintAnswerToLife()
      {
          await Task.Delay(5000);
          int answer = 21 * 2;
          Console.WriteLine(answer);
      }
      Task PrintAnswerToLife()
      {
          var tcs = new TaskCompletionSource<object>();
          var awaiter = Task.Delay(5000).GetAwaiter();
          awaiter.OnCompleted(() =>
          {
              try
              {
                  awaiter.GetResult();
                  int answer = 21 * 2;
                  Console.WriteLine(answer);
                  tcs.SetResult(null);
              }
              catch (Exception ex)
              {
                  tcs.SetException(ex);
              }
          });
          return tcs.Task;
      }*/

    async Task<string> GetWebPageAsync(string uri)
    {
        string html;
        if (_catch.TryGetValue(uri, out html)) return html;
        return _catch[uri] = await new WebClient().DownloadStringTaskAsync(uri);
    }

    Task<string> GetWebPageAsync2(string uri)
    {
        lock (taskCatch)
            if (taskCatch.TryGetValue(uri, out var downloadTask)) return downloadTask;
            else
                return taskCatch[uri] = new WebClient().DownloadStringTaskAsync(uri);

    }

    async Task Go()
    {
        try
        {
            _results.Text += await GetWebPageAsync2("http://www.albahari.com");
        }
        catch (WebException ex)
        {
            _results.Text += "Error: " + ex.Message;

        }
        finally
        {
            //button.IsEnabled = true;
        }
    }


    /*async Task Go()
    {
        await PrintAnswerToLife();
        Console.WriteLine("Done");
    }
    async Task PrintAnswerToLife()
    {
        int answer = await GetAnswerToLife();
        Console.WriteLine(answer);
    }
    async Task<int> GetAnswerToLife()
    {
        await Task.Delay(5000);
        int answer = 21 * 2;
        return answer;
    }*/

    int GetPrimesCount(int start, int count)
    {
        return ParallelEnumerable.Range(start, count).Count(n =>
            Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0));
    }

    Task<int> GetPrimesCountAsync(int start, int count)
    {
        return Task.Run(() => ParallelEnumerable.Range(start, count).Count(n =>
            Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));
    }
}